//   Copyright 2012,2013 Vaughn Vernon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package com.saasovation.collaboration.port.adapter.service;


import com.saasovation.collaboration.domain.model.collaborator.Collaborator;
import com.saasovation.collaboration.domain.model.tenant.Tenant;
import org.springframework.http.HttpStatusCode;
import org.springframework.lang.NonNull;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

public class HttpUserInRoleAdapter implements UserInRoleAdapter {

    private static final String HOST = "localhost";
    private static final String PORT = "8081";
    private static final String PROTOCOL = "http";
    private static final String URL_TEMPLATE = "/idovation/tenants/{tenantId}" +
            "/users/{username}/inRole/{role}";
    private static final String URI = PROTOCOL + "://" + HOST + ":" + PORT + URL_TEMPLATE;

    public HttpUserInRoleAdapter() {
        super();
    }

    public <T extends Collaborator> T toCollaborator(Tenant aTenant,
                                                     String anIdentity,
                                                     String aRoleName,
                                                     Class<T> aCollaboratorClass) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            protected boolean hasError(@NonNull HttpStatusCode statusCode) {
                int statusValue = statusCode.value();
                // not an error, return null
                if (statusValue == 204) {
                    return false;
                }
                return super.hasError(statusCode);
            }
        });
        String result;
        try {
            result = restTemplate.getForObject(URI,
                    String.class,
                    aTenant.id(),
                    anIdentity,
                    aRoleName);
        } catch (RestClientException e) {
            throw new IllegalStateException(
                    "There was a problem requesting the user: "
                            + anIdentity
                            + " in role: "
                            + aRoleName
                            + " with resulting message: "
                            + e.getMessage());
        }
        if (result == null || result.isEmpty()) {
            return null;
        }
        try {
            return new CollaboratorTranslator()
                    .toCollaboratorFromRepresentation(
                            result,
                            aCollaboratorClass);
        } catch (Throwable t) {
            throw new IllegalStateException(
                    "Failed because: " + t.getMessage(), t);
        }
    }
}
